iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0

本系列文章經過重新編排和擴充,已出書為ECMAScript關鍵30天。原始文章因當時準備時程緊迫,多少有些許錯誤。為了避免造成讀者的困擾,以及配合書籍的內容規劃,將會陸續更新本系列文章。
本篇文章在 2021/11/5 已更新。

symbol 是在 ES2015 中新增加的內建資料型態。今天就來認識新面孔,並且了解基本應用吧!

Symbol(description)

symbol是在 ES2015 後的第 7 種基本型別。以一句話來介紹,以這種型態宣告的值,每次都是不同的。這種資料型態的出現,也讓物件在新增屬性上有相當的擴充。

在 ES5 以前,物件的屬性名稱只能接受字串類型;但在 ES2015 後,屬性名稱的類型除了字串以外,還可以接受symbol型態的值。這麼做的用意是,因為每次宣告的值都不一樣,所以可以保證不會因名稱重複,而被覆寫屬性值的問題。

先看看簡單的例子。

let s = Symbol(),
  s1 = Symbol();
typeof s; // symbol
console.log(s === s1); // false

在宣告symbol的變數時,可選擇性的傳入關於變數的描述。

在物件中如何以symbol建立屬性以及取用呢?直接以例子看看

const prop = Symbol('prop is property name');

// way 1
const obj = {...};
obj[prop] = "Hi";
obj.prop = "Bye";

console.log(obj.prop) // "Bye" 因為用點運算子連接的屬性名稱會被當作字串
console.log(obj[prop]) // "Hi"

// way 2: Object Literals
const obj = {
    [prop]:"Hi"
};

// way 3: Object.defineProperty
const obj = {...};
Object.defineProperty(obj, prop, {value: 'Hi'});

Symbol.for(key)

如果要建立全域的常數可以重複使用時,使用 Symbol.for來宣告。如果 key 已經存在,就不會再重新建立新的變數。

let s = Symbol.for("Woman"),
  s1 = Symbol.for("Woman");

console.log(s === s1); // true

Symbol.keyFor(symbol)

用來取得以 Symbol.for 宣告的全域常數的 key 值。

let s = Symbol.for("Woman"),
console.log(Symbol.keyFor(s)); // "Woman"

Object.getOwnPropertySymbols(obj)

在昨天,我們有提到物件的迭代中的可列舉屬性。而 symbol型態的屬性名稱比較特別,這類的屬性無法使用Object.keys()for...inJSON.stringify()等迭代可列舉屬性的方法。

如果要迭代這類屬性的話,則需使用 Object.getOwnPropertySymbols,回傳各 symbol 值的陣列。

const obj = {
  name: "One Punch Man",
  lead: "Saitama",
  [Symbol("prop1")]: "prop1",
  [Symbol.for("prop2")]: "prop2",
};

for (let i in obj) {
  console.log(i);
}
// "One Punch Man"
// "Saitama"

const smblProps = Object.getOwnPropertySymbols(obj);
// [Symbol(props1), Symbol(props2)]

最後,我們試著以最常使用的場景,來體驗看看應用吧。

假設我們要以 switch case 根據資料裡的 type 屬性來寫判斷的處理函式。

function handleFile(data) {
  switch (data.type) {
    case T_PDF:
      convertPDF(data);
      break;
    case T_DOC:
      convertDOC(data);
      break;
    case T_IMAGE:
      convertImage(data);
      break;
    default:
      throw new Error("Unknown type of data");
  }
}

我們只在乎 type 的常數有沒有存在,而且值不重複。而不需要在意值的內容是什麼。

// ES5
const T_PDF = "T_PDF",
  T_DOC = "T_DOC",
  T_IMAGE = "T_IMAGE";

//ES2015
const T_PDF = Symbol(),
  T_DOC = Symbol(),
  T_IMAGE = Symbol();

小結

今天介紹的 symbol是一種嶄新的資料型態,雖然已經推出 5 年了,可是還是很少應用在專案上。今天了解在特定的開發情境中,其實用 symbol 還蠻恰當的。希望大家也能嘗試著大膽使用看看喔!

參考資源


上一篇
ES2015(ES6) - Object
下一篇
ES2015(ES6) - Set 、 Map
系列文
從ES到ESNext - 30天輕鬆掌握ECMAScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言